// Go 的 map 底层是一个哈希表，包含 buckets（桶）、key-value 对、以及一些元数据（如长度、是否正在扩容等）。当多个 goroutine 同时修改 map 时，可能出现以下问题：

// a. 数据竞争（Data Race）
// 两个 goroutine 同时修改同一个 bucket 或字段（如 map 的长度 len），CPU 缓存不一致、指令重排等会导致结果不可预测。

// b. 破坏内部结构
// 例如：

// 一个 goroutine 正在扩容（rehashing）map；
// 另一个 goroutine 同时在插入新元素； → 可能导致指针错乱、内存越界，甚至 panic: concurrent map read and map write（Go 1.6+ 会主动检测并 panic，防止更严重的后果）。

// ✅ 方法一：使用互斥锁（推荐用于一般场景）
// ✅ 方法二：使用 sync.Map（适用于读多写少、key 集合动态变化的场景）

package main

import (
	"fmt"
	"sync"
)

var m = map[int]string{
	1: "枫枫",
	2: "小明",
	3: "洋洋",
}

var wait sync.WaitGroup
var lock sync.Mutex

func reader() {
	defer wait.Done()
	lock.Lock()
	for i := 0; i < 100; i++ {
		fmt.Printf("m[i%%3]: %#v\n", m[i%3+1])
	}
	lock.Unlock()
}

func writer() {
	defer wait.Done()
	lock.Lock()
	for i := 0; i < 100; i++ {
		m[i%3+1] = fmt.Sprintf("trash%d", i)
	}
	lock.Unlock()
}

func main() {
	wait.Add(2)
	go reader()
	go writer()
	wait.Wait()
}
